﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Windows.Forms.DataVisualization.Charting;

namespace SpeechRecognition
{
    public partial class MainWindow : Form
    {
        Recognizer rec;
        DirectoryInfo inputDirectory;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void readToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.ClearCharts();

            try
            {
                double bound = Convert.ToDouble(txtBound.Text);
                rec = new Recognizer(bound);
                if (openFileDialogWAV.ShowDialog() == DialogResult.OK)
                {
                    rec.ReadFromFile(openFileDialogWAV.FileName);
                    for (int i = 0; i < rec.SpeechSignal.Count; i++)
                    {
                        chartSpeechSignal.Series[0].Points.AddXY(i, rec.SpeechSignal[i]);
                    }

                    rec.Normalization();
                    for (int i = 0; i < rec.NormalizedSignal.Count; i++)
                    {
                        chartNormalizedSignal.Series[0].Points.AddXY(i, rec.NormalizedSignal[i]);
                    }

                    rec.LegendreFunction();
                    numericSpectrums.Maximum = rec.Spectrum.GetLength(0);
                    for (int i = 0; i < rec.Spectrum.GetLength(1); i++)
                    {
                        chartSpectrumTime.Series[0].Points.AddXY(i, rec.Spectrum[0, i]);
                    }

                    rec.CalculateBands();
                    rec.CalculateFilteredBands();
                    numericBands.Maximum = rec.OctaveBand.GetLength(0);
                    for (int i = 0; i < rec.OctaveBand.GetLength(1); i++)
                    {
                        chartOctaveBands.Series[0].Points.AddXY(i, rec.OctaveBand[0, i]);
                        chartOctaveBands.Series[1].Points.AddXY(i, rec.FilteredOctaveBand[0, i]);
                    }

                    rec.MakeSegmentation();
                    for (int i = 0; i < rec.Segmentation.Length; i++)
                    {
                        chartSegmentation.Series[0].Points.AddXY(i, rec.Segmentation[i]);
                    }

                    foreach (int index in rec.SegmentationMaxValues)
                    {
                        Series s = new Series();
                        s.ChartType = SeriesChartType.Line;
                        s.Points.AddXY(index, 0);
                        s.Points.AddXY(index, rec.Segmentation.Max() + 0.01);
                        s.Color = Color.Red;
                        s.BorderDashStyle = ChartDashStyle.Dash;
                        chartSegmentation.Series.Add(s);
                    }
                }
            }
            catch (ArgumentOutOfRangeException ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (FormatException)
            {
                MessageBox.Show("Please input correct data!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void MainWindow_Load(object sender, EventArgs e)
        {
            inputDirectory = new DirectoryInfo(".\\Data");
            if (!inputDirectory.Exists)
            {
                inputDirectory.Create();
            }
            openFileDialogWAV.InitialDirectory = inputDirectory.FullName;
        }

        private void numericSpectrums_ValueChanged(object sender, EventArgs e)
        {
            int num = Convert.ToInt32(numericSpectrums.Value);
            RedrawChart(num, chartSpectrumTime, rec.Spectrum);
        }

        private void RedrawChart(int num, Chart chart, double[,] data, double[,] secondData = null)
        {
            chart.Series[0].Points.Clear();
            for (int i = 0; i < data.GetLength(1); i++)
            {
                chart.Series[0].Points.AddXY(i, data[num - 1, i]);
            }
            if (secondData != null)
            {
                chart.Series[1].Points.Clear();
                for (int i = 0; i < secondData.GetLength(1); i++)
                {
                    chart.Series[1].Points.AddXY(i, secondData[num - 1, i]);
                }
            }
        }

        private void numericBands_ValueChanged(object sender, EventArgs e)
        {
            int num = Convert.ToInt32(numericBands.Value);
            RedrawChart(num, chartOctaveBands, rec.OctaveBand, rec.FilteredOctaveBand);
        }

        private void ClearCharts()
        {
            this.chartSpeechSignal.Series[0].Points.Clear();
            this.chartNormalizedSignal.Series[0].Points.Clear();
            this.chartSpectrumTime.Series[0].Points.Clear();
            this.chartOctaveBands.Series[0].Points.Clear();
            this.chartOctaveBands.Series[1].Points.Clear();
            this.chartSegmentation.Series[0].Points.Clear();
            int count = chartSegmentation.Series.Count;
            for (int i = 1; i < count; i++ )
            {
                this.chartSegmentation.Series.RemoveAt(1);
            }
        }
    }
}
